<?php

require_once(dirname(__FILE__) . '/Event.php');

/**
 * Basic EventDispatcher class
 * @link http://help.adobe.com/ru_RU/AS3LCR/Flash_10.0/flash/events/EventDispatcher.html
 * @author Gvozd
 */
class EventDispatcher {

    /**
     * @var array
     */
    protected $events = array();

    /**
     *
     * @param string $type
     * @param callback $listener,
     * @param  boolean $useCapture unsupported
     * @param int $priority unsupported
     * @param boolean $useWeakReference unsupported
     * @return void
     */
    public final function addEventListener($type, $listener /*, $useCapture = false, $priority = 5, $useWeakReference = false*/) {
        if (!is_callable($listener)) {
            throw new DieException('The contents of a variable can not be called as a function');
        }
        if (!isset($this->events[$type])) {
            $this->events[$type] = array();
        }
        $this->events[$type][] = $listener;
    }

    /**
     *
     * @param string $type
     * @param callback $listener
     * @param false $useCapture unsupported
     * @return void
     */
    public final function removeEventListener($type, $listener /*, $useCapture = false*/) {
        if (!is_callable($listener)) {
            throw new DieException('The contents of a variable can not be called as a function');
        }
        if (isset($this->events[$type]) && is_array($this->events[$type])) {
            $deleteKeys = array_keys($this->events[$type], $listener);
            foreach ($deleteKeys as $key) {
                unset($this->events[$type][$key]);
            }
        }
        if (empty($this->events[$type])) {
            unset($this->events[$type]);
        }
    }

    /**
     *
     * @param string $type
     * @return boolean
     */
    public final function hasEventListener($type) {
        if (!emty($this->events[$type])) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @return boolean
     */
    public final function hasSomeEventListener() {
        foreach ($this->events as $eventName => $eventListenters) {
            if (empty($eventListenters)) {
                unset($this->events[$eventName]);
            }
        }
        if (empty($this->events)) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * @param Event $event
     */
    public final function dispatchEvent(Event $event) {
        $eventName = $event->type;
        if (isset($this->events[$eventName]) && is_array($this->events[$eventName])) {
            foreach ($this->events[$eventName] as $key => $eventHandler) {
                $event->setEnvironment($this, $eventHandler);
                try {
                    call_user_func($eventHandler, $event);
                } catch (DieException $e) {
                    echo 'Caught exception: ', $e->getMessage(), "\n";
                }
            }
        }
    }

    /**
     * unsupported
     * @param string $type
     * @return boolean 
     */
    public final function willTrigger($type) {
        throw new DieException('Method unsupported');
        return false;
    }

}
